/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pacificlms.MainPanel;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import pacificlms.LoggedMember;
import pacificlms.DataHolder;
import pacificlms.MasterConnection;
import pacificlms.Verifiable.Database.*;

//import pacificlms.Verifiable.Database.Resource;
//import pacificlms.Verifiable.Database.Copy;
import pacificlms.Verifiable.VerifiableObject;

/**
 *
 * @author Yasir Tanveer
 */
public class ActionCheckOutCopyofResource extends CentralUIPanel {

    /**
     * Creates new form ActionCheckOutCopyofResource
     */
    public ActionCheckOutCopyofResource() {
        super(null);
        initComponents();
        
        txtMemberCard.setText(LoggedMember.getInstance().LibraryCardNumber(null));
        
        if (!LoggedMember.getInstance().IsLibrarian())
        {
            txtMemberCard.setEnabled(false);
        }
    }
    
    @Override
    public String TabName()
    {
        return "Check Out";
    }
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel3 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        txtMemberCard = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        txtCallNumber = new javax.swing.JTextField();
        btnCheckOut1 = new javax.swing.JButton();
        btnClose = new javax.swing.JButton();

        setFont(new java.awt.Font("Tahoma", 0, 22)); // NOI18N
        setPreferredSize(new java.awt.Dimension(615, 535));
        setLayout(null);

        jLabel3.setFont(new java.awt.Font("Tahoma", 0, 22)); // NOI18N
        jLabel3.setText("Check Out");
        add(jLabel3);
        jLabel3.setBounds(10, 0, 200, 20);

        jLabel6.setText("For Member");
        add(jLabel6);
        jLabel6.setBounds(10, 41, 105, 14);
        add(txtMemberCard);
        txtMemberCard.setBounds(119, 38, 235, 20);

        jLabel7.setText("Call Number");
        add(jLabel7);
        jLabel7.setBounds(10, 72, 105, 14);
        add(txtCallNumber);
        txtCallNumber.setBounds(119, 69, 235, 20);

        btnCheckOut1.setText("Check Out");
        btnCheckOut1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCheckOut1ActionPerformed(evt);
            }
        });
        add(btnCheckOut1);
        btnCheckOut1.setBounds(119, 100, 100, 23);

        btnClose.setText("Close");
        btnClose.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCloseActionPerformed(evt);
            }
        });
        add(btnClose);
        btnClose.setBounds(505, 501, 100, 23);
    }// </editor-fold>//GEN-END:initComponents
//when checkout set hold to 1 if it exists for this member
    int NumOfAvailableCopy(String RCode, String IDCode)
    {
        try
        {
            RCode = VerifiableObject.ConvertToMYSQLString(RCode);
            IDCode = VerifiableObject.ConvertToMYSQLString(IDCode);
            Connection con = MasterConnection.getInstance();
            Statement stmt = con.createStatement();
            String ResourceCode = RCode;
            int CopyCount, CheckOutCount, HoldCount;
            String SQL = "SELECT Count(*) AS CopyCount FROM copy C WHERE C.resourcecode = "+(ResourceCode)+" AND C.CopyStatus = 'available'";
            String SQL1 = "SELECT Count(*) AS CheckOutCount FROM CheckOut CO WHERE CO.resourcecode ="+(ResourceCode)+" AND CO.Finished = '0'";
            String SQL2 = "SELECT Count(*) AS HoldCount FROM hold H  WHERE NOT EXISTS (SELECT * FROM hold H2 WHERE H2.IdentityNumber = "+(IDCode)+" AND H2.resourcecode ="+(ResourceCode)+" AND H2.Finished='0') AND H.resourcecode ="+(ResourceCode)+" AND H.Finished = '0'";
            
            ResultSet RS = stmt.executeQuery(SQL);
            RS.next();
            CopyCount = RS.getInt("CopyCount");
            
            RS = stmt.executeQuery(SQL1);
            RS.next();
            CheckOutCount = RS.getInt("CheckOutCount");
            
            RS = stmt.executeQuery(SQL2);
            RS.next();
            HoldCount = RS.getInt("HoldCount");
            
            return CopyCount-CheckOutCount-HoldCount;
        }
        catch(Exception Ex)
        { 
            JOptionPane.showMessageDialog(null, "Database error, please try again later\n" + Ex.getMessage(), "Database Error", JOptionPane.ERROR_MESSAGE);
            return 999;
        }  
        
    }
    
    private Copy GetCopy()
    {
        try
        {
            Copy Cpy = new Copy();
            String CallNumber = txtCallNumber.getText();
            Cpy.CallNumber(CallNumber);

            String FindCopySQL = Cpy.FindIdenticalSQL();
            Connection Conn = MasterConnection.getInstance();
            Statement stmt = Conn.createStatement();
            ResultSet CopyRS = stmt.executeQuery(FindCopySQL);

            if (!CopyRS.next())
            {
                return null;
            }
            Cpy = (Copy)Copy.CreateFromResultSet(Copy.class, CopyRS, CopyRS.getMetaData());

            return Cpy;
        }
        catch(SQLException Ex)
        {
            return null;
        }
    }
    
    void CheckOut()
    {
        Copy Copy;
        CourseReserve CourseReserve;
        Resource Resource;
        Member Memb;
        
        String CallNumber = txtCallNumber.getText();
        
        //check if call number is empty
        if(CallNumber.isEmpty())
        {
            JOptionPane.showMessageDialog(null, "The CallNumber can not be empty.", "Validation Warning", JOptionPane.WARNING_MESSAGE);
            return;
        }
        
        try
        {
            Connection con = MasterConnection.getInstance();
            Statement stmt = con.createStatement();
            
            //check if member is logged in
            if(LoggedMember.getInstance().IsNonmember())
            {
                JOptionPane.showMessageDialog(null, "Non member can't check out resource, please login first.", "Validation Warning", JOptionPane.WARNING_MESSAGE);
                return;
            }

            //check if call nubmer referes to copy
            Copy = GetCopy();
            if(Copy == null)
            {
                JOptionPane.showMessageDialog(null, "Unable to find copy with the CallNumber " + CallNumber, "Validation Warning", JOptionPane.WARNING_MESSAGE);
                return;
            }
            
            //check that copy is not damaged, lost or retired
            if (!Copy.GoodStatus())
            {
                JOptionPane.showMessageDialog(null, "Copy is not in good enough condition to check out.", "Validation Warning", JOptionPane.WARNING_MESSAGE);
                return;
            }
                
            //check that copy is not reserved
            String copynumber = Copy.CopyNumber(null);
            String resourcecode = Copy.ResourceCode(null);
            CourseReserve = new CourseReserve();
            CourseReserve.ResourceCode(resourcecode);
            if(CourseReserve.IsReserved()) 
            {
                JOptionPane.showMessageDialog(null, "This resource has been reserved. You can't check it out.", "Validation Warning", JOptionPane.WARNING_MESSAGE);
                return;
            }

            //check that copy is not reference only material
            Resource = new Resource();
            Resource.ResourceCode(resourcecode);
            String ResourceSQL = Resource.FindIdenticalSQL();
            ResultSet ResourceRS = stmt.executeQuery(ResourceSQL);
            Resource = null;
            if(ResourceRS.next())
            {
                Resource = (Resource)Resource.CreateFromResultSet(Resource.class, ResourceRS, ResourceRS.getMetaData());
            }
            if(Resource == null || Resource.IsReference())
            {
                JOptionPane.showMessageDialog(null, "This resource can only be used in the library.", "Validation Warning", JOptionPane.WARNING_MESSAGE);
                return;
            }
            
            //check that member does not have unpaid fines
            Memb = new Member();
            String LibCard = txtMemberCard.getText();
            if (LibCard.isEmpty())
            {
                Memb = LoggedMember.getInstance();
            }
            else
            {
                Memb.LibraryCardNumber(LibCard);
                String MemberFindSQL = Memb.FindIdenticalSQL();
                ResultSet Mrs = stmt.executeQuery(MemberFindSQL);
                if(Mrs.next())
                {
                     Memb.FillFromResultSet(Mrs, Mrs.getMetaData());
                }
                   
                else
                {
                    JOptionPane.showMessageDialog(null, "Unable to find member "+LibCard+".", "Validation Warning", JOptionPane.WARNING_MESSAGE);
                    return;
                }
                    
            }
            double TotalFine = Memb.GetTotalFine();
            if(TotalFine > 0) 
            {    
                JOptionPane.showMessageDialog(null, "You has unpaid fines of $"+TotalFine+". Please pay your fines making any check outs\n", "Validation Warning", JOptionPane.WARNING_MESSAGE);
                return;
            }

            if (NumOfAvailableCopy(Copy.ResourceCode(null), Memb.IdentityNumber(null)) <= 0) {
                JOptionPane.showMessageDialog(null, "This resource has no available copy in the library.", "Validation Warning", JOptionPane.WARNING_MESSAGE);
                return;
            }
            
            //check that member has not checked out tioo many resources
            Setting Limit = DataHolder.GetSetting("Check Out limit");
            int CheckOutLimit = Integer.parseInt(Limit.Value(null));
            if(CheckOut.CheckoutAmount(Memb) >= CheckOutLimit)
            { 
                JOptionPane.showMessageDialog(null, "You already have "+CheckOutLimit+" items checked out.\nYou must check some in before checking anything else out.\n", "Validation Warning", JOptionPane.WARNING_MESSAGE);
                return;
            }

            //check that the copy specified is not already checked out
            CheckOut CurrentCheckOut = new CheckOut();
            CurrentCheckOut.ResourceCode(resourcecode);
            CurrentCheckOut.CopyNumber(copynumber);
            CurrentCheckOut.Finished("0");
            String SQLAlreadyCheckOut = CurrentCheckOut.FindIdenticalSQL();
            ResultSet RsOut = stmt.executeQuery(SQLAlreadyCheckOut);
            CurrentCheckOut = null;
            if (RsOut.next())
            {
                CurrentCheckOut = (CheckOut)CurrentCheckOut.CreateFromResultSet(CheckOut.class, RsOut, RsOut.getMetaData());
            }
            if (CurrentCheckOut != null)
            {
                JOptionPane.showMessageDialog(null, "This item is already checked out.\n", "Validation Warning", JOptionPane.WARNING_MESSAGE);
                return;
            }
        }
        catch(Exception Ex)
        {
            JOptionPane.showMessageDialog(null, "Database error, please try again later\n" + Ex.getMessage(), "Database Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        
        
        
        CheckOut CO = new CheckOut();
        
        CO.ResourceCode(Copy.ResourceCode(null));
        CO.CopyNumber(Copy.CopyNumber(null));
        CO.IdentityNumber(Memb.IdentityNumber(null));
               
        CO.Finished("0");
        CO.LateFine("0.00");
        CO.CopyConditionFine("0.00");
        CO.Payment("0.00");
        CO.RenewalCount("0");
        CO.CheckInDate("");
        CO.CopyStatus("checked out");
        
        GregorianCalendar now= new GregorianCalendar();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        
	String DueDate;
        
        String MTpye = Memb.Type(null);
        String RTpye = Resource.Type(null);
        
        CheckOutRule COR = DataHolder.GetCheckOutRule(MTpye, RTpye);
        int Days = 0;
        if(COR != null)
        {
            Days = Integer.parseInt(COR.CheckOutDays(null));
        }
        else
        {
            Days = 14;
        }
        
        now.add(Calendar.DATE, Days);
        DueDate = sdf.format(now.getTime());
        
        CO.DueDate(DueDate);
        
        try
        {
            Connection con = MasterConnection.getInstance();
            Statement stmt = con.createStatement();
            
            if (CO.Verify())
            {
                String InsertSQL = CO.InsertRecrodSQL();
                stmt.executeUpdate(InsertSQL);
                Hold Hold = new Hold();
                Hold.ResourceCode(Copy.ResourceCode(null));
                Hold.IdentityNumber(Memb.IdentityNumber(null));
                ResultSet HoldRS = stmt.executeQuery(Hold.FindIdenticalSQL());
                if (HoldRS.next())
                {
                    Hold.FillFromResultSet(HoldRS, HoldRS.getMetaData());
                    Hold.Finished("1");
                    if (!Hold.Verify())
                    {
                        throw new Exception("Unable to finish hold");
                    }
                    stmt.executeUpdate(Hold.UpdateRecrodSQL());
                }
            }
            else
                throw new Exception("Unable to verify");
        }
        catch(Exception Ex)
        {
            JOptionPane.showMessageDialog(null, "Database error, please try again later\n" + Ex.getMessage(), "Database Error", JOptionPane.ERROR_MESSAGE);
            return;
        }

        JOptionPane.showMessageDialog(null, Resource.Title(null) + " has been checked out successfully\nPlease return it by " + DueDate, "Success", JOptionPane.INFORMATION_MESSAGE);
    }
    
    private void btnCheckOut1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckOut1ActionPerformed
        CheckOut();
    }//GEN-LAST:event_btnCheckOut1ActionPerformed

    private void btnCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCloseActionPerformed
        Close();
    }//GEN-LAST:event_btnCloseActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnCheckOut1;
    private javax.swing.JButton btnClose;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JTextField txtCallNumber;
    private javax.swing.JTextField txtMemberCard;
    // End of variables declaration//GEN-END:variables
}
